/*
 * $Id: GeoIPUtilities.java 42 2013-04-17 15:33:59Z gabakyan $
 * $Author: gabakyan $
 * $Revision: 42 $
 * $Date: 2013-04-17 15:33:59 +0000 (Wed, 17 Apr 2013) $
 *
 * Copyright (c) 2013 Supply Chain Intelligence (SCI), Inc.
 * http://www.scintelligence.com/, Email: info@scintelligence.com
 * All rights reserved.
 *
 * This file is part of Logistics Map.
 *
 * Logistics Map is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * Logistics Map is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Logistics Map.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.sci.logisticsmap.service.support;

import com.maxmind.geoip.LookupService;
import com.sci.logisticsmap.support.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * The utility class which provides helper methods for manipulating the GeoIP.
 *
 * @author gabakyan@gmail.com (Last modified by $Author: gabakyan $)
 * @version $Revision: 42 $
 */
@Component
public class GeoIPUtilities {
    /**
     * The logger.
     */
	private static final Logger logger = LoggerFactory.getLogger(GeoIPUtilities.class);

    /**
     * The GeoIP database filename.
     */
	private static final String DATABASE_FILENAME = "GeoIP.dat";
    /**
     * The GeoIP v6 database filename.
     */
	private static final String DATABASE_FILENAME_V6 = "GeoIPv6.dat";

    /**
     * The IP lookup service.
     */
    private LookupService lookupService;
    /**
     * The IP v6 lookup service.
     */
    private LookupService lookupServiceV6;

    private @Value("${geoIPUtilities.databaseFileLocation}") String databaseFileLocation;

    /**
     * The default constructor.
     */
    public GeoIPUtilities() {
    }

    /**
     * The post construct initialization method.
     */
    @PostConstruct
    public void init() {
        try {
            String dbfile = databaseFileLocation + Constants.FILE_SEPARATOR + DATABASE_FILENAME;
            String dbfileV6 = databaseFileLocation + Constants.FILE_SEPARATOR + DATABASE_FILENAME_V6;
            logger.debug("Geo IP database file path = {}", dbfile);
            logger.debug("Geo IPV6 database file path = {}", dbfileV6);
            // You should only call LookupService once, especially if you use
            // GEOIP_MEMORY_CACHE mode, since the LookupService constructor takes up
            // resources to load the GeoIP.dat file into memory
            //lookupService = new LookupService(dbfile,LookupService.GEOIP_STANDARD);
            lookupService = new LookupService(dbfile,LookupService.GEOIP_MEMORY_CACHE);
            lookupServiceV6 = new LookupService(dbfileV6,LookupService.GEOIP_MEMORY_CACHE);

            //lookupService.close();
            //lookupServiceV6.close();
	    } catch (Exception e) {
            logger.debug("Geo IP database files loading", e);
        }
    }

    /**
     * Retrieves the country code by the IP address.
     *
     * @param ipAddress The IP address.
     *
     * @return The country code.
     */
    public String getCountryCode(String ipAddress) {
        if (lookupService != null) {
            return lookupService.getCountry(ipAddress).getCode();
        }
        return null;
    }

    /**
     * Retrieves the country code by the IP v6 address.
     *
     * @param ipAddress The IP v6 address.
     *
     * @return The country code.
     */
    public String getCountryCodeV6(String ipAddress) {
        if (lookupService != null) {
            return lookupServiceV6.getCountryV6(ipAddress).getCode();
        }
        return null;
    }
}
